{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用tensorflow实现识别mnist手写数组识别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/mengni/anaconda3/envs/DL/lib/python3.6/site-packages/matplotlib/__init__.py:1078: UserWarning: Illegal line #1\n",
      "\t\"TkAgg\n",
      "\"\n",
      "\tin file \"/Users/mengni/.matplotlib/matplotlibrc\"\n",
      "  warnings.warn('Illegal %s' % error_details)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "tf.logging.set_verbosity(tf.logging.INFO)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./train-images-idx3-ubyte.gz\n",
      "Extracting ./train-labels-idx1-ubyte.gz\n",
      "Extracting ./t10k-images-idx3-ubyte.gz\n",
      "Extracting ./t10k-labels-idx1-ubyte.gz\n",
      "(55000, 784)\n",
      "(55000, 10)\n",
      "(5000, 784)\n",
      "(5000, 10)\n",
      "(10000, 784)\n",
      "(10000, 10)\n"
     ]
    }
   ],
   "source": [
    "mnist = input_data.read_data_sets('./',one_hot=True)\n",
    "\n",
    "print(mnist.train.images.shape)\n",
    "print(mnist.train.labels.shape)\n",
    "\n",
    "print(mnist.validation.images.shape)\n",
    "print(mnist.validation.labels.shape)\n",
    "\n",
    "print(mnist.test.images.shape)\n",
    "print(mnist.test.labels.shape)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "查看数据，可以看到，images数据是28*28长度的一维向量，有55000个训练数据和对应的label，5000个验证数据和对应的label，10000个测试数据和对应的label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n1tfEdYdWctolT/w14vNvvMEukek58DsT313nN6ddjjv95Phhc/NA6c/IDcux1YOjnQfONnGHN+08\nfLM7Jjvtktu0NPH8f6Q7dbNPfcHEwSUzt9Zc7L7Yxzb8qmtTpypn46aIfYRIk76rTTzwc7sub/bm\nQ5x2NQMr/XIWLpFIMmRzxLpjXvibiReeY+eHO95+s9OuwcOl7/s63AkDAOAJSRgAAE/KzXB0UiU7\n/Dh/SHsTLz7HHfZ6Zqsdwnrv/jNN3PzdsKGuDDu8OLN5R6dOn2PXRqTstksoUr6eXthuIwr/O/H5\nQMn9XDnwD7vkod75c2N6/jov2mv/zQa7Zdbdw3/Lr3m+Fnxuf68aMBwtIiIqxf3zU6FLdMO7h/3P\nDjG2DBuCDsqZt8i26+3WndjPjoE+ducIE3etlOW0Cw5Pf51+uPskDEcXKGfLFhPPGGmndGoscZcJ\n5SyMPBUUreRd+d9PtuuxwClve7jIL1XsuBMGAMATkjAAAJ6QhAEA8CRh54STqrjb1K1+s7GJF3e2\nyxOe2tLSaTfh5pNNnPbtzxGfP/hV+ipbtjt1gyZPNPGodfar+du+PkCnEZPDK9htJsO3xJu60C4r\nyZCiz+Glz7bzuT/sdZc51Z6THd7c0CpiVbmV3KiBU5565Fv5tntmazOn3PoFO9eYE944SnVG2Lnk\nsX2PMnHXepHnmBG72qP8/Lv2rPO7U35DGkRo6Q93wgAAeEISBgDAk4Qajg4OQc9/8jCnLjgE/cTm\nVib+rldbp13yssJ/XX7lte6QdrfKE0y8+SD7fK/WaO+0y9m6rdCvhb86ZfaFJv7ysHedujFdR5n4\nIXGXkkUru5vdVe2gB+w0RLMU9/rVuX2ZiXd95D6Hyv/c8nJt+aX1Itbt1HYZy9sPn+nUVZ8beZoo\nFkuvbWLiH8e7p6V1qRgy8aJ+bn+b3Wt3hNLZkaciUPwyz+rslK/tPjHfdh9u6BT2k9K3PJA7YQAA\nPCEJAwDgSUINR/95ZQcTL+71rFP3yW67yf9357Yzcfay5UV+3X3VI481zttrh7AYfo6PtEH21/j5\n992pgX7VF5p44XNHm7jtf9c67dafbr81ec5Nk5y63jXsoR71UoKnNLgnNrzabLyJe/ZwN47Prsx4\ntIhIcu1aJr7zmncjtnt/h/1We/U3inf4OVzOHLur0jUT+jl1i3vZaax5vd2/KWd/ENiGa9rs+HSu\n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\n4hLFAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x120aa0320>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 取出前16个数据查看，需要把一维数据转换成二维图片，然后显示图片和对应的label\n",
    "\n",
    "plt.figure(figsize=(8,8))\n",
    "\n",
    "for idx in range(16):\n",
    "    plt.subplot(4,4,idx+1)\n",
    "    plt.axis('off')\n",
    "    # 由于前面取出数据时使用了one_hot=True， 因此需要使用argmax进行还原\n",
    "    plt.title('[{}]'.format(np.argmax(mnist.train.labels[idx])))\n",
    "    plt.imshow(mnist.train.images[idx].reshape((28,28)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里我们直接使用上面的数据作为输入，所以定义两个placeholder分别用于图像和lable数据，另外，定义一个bool类型的变量用于标识当前网络是否正在训练。\n",
    "\n",
    "为了让网络更高效的运行，多个数据会被组织成一个batch送入网络，两个placeholder的第一个维度就是batchsize，因为我们这里还没有确定batchsize，所以第一个维度留空。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = tf.placeholder('float',[None,784],name='x')\n",
    "y = tf.placeholder('float',[None,10],name='y')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 因为我们输入的是图片展开后的一维向量，所以需要先把一维向量还原为二维的图片。\n",
    "\n",
    "x_image = tf.reshape(x,[-1,28,28,1])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "定义第一个卷积层【C1】，使用6个5x5的卷积核对输入数据进行卷积，padding方式选择valid，所以输出数据的宽高变成24x24，但是深度从原来的1变成了6.本层卷积的激活函数为relu。\n",
    "\n",
    "$(H,w)_{output} = ((H,W)_{input}-(H,W)_{kernel}+padding*2)/stride + 1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('conv1'):\n",
    "    C1 = tf.contrib.slim.conv2d(\n",
    "    x_image,6,[5,5],padding='VALID',activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来进行stride为2的最大池化【S2】，池化后，输出深度不变，但是长宽减半，所以输出变成了12x12，深度为6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('pool1'):\n",
    "    S2 = tf.contrib.slim.max_pool2d(\n",
    "        C1,[2,2],stride=[2,2],padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们定义第二个卷积层【C3】，\n",
    "\n",
    "  卷积核： 16个5x5\n",
    "  \n",
    "padding： valid\n",
    "\n",
    "   输出： 8x8 深度为16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('conv2'):\n",
    "    C3 = tf.contrib.slim.conv2d(\n",
    "    S2,16,[5,5],padding='VALID',activation_fn=tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再一次stride=2的最大池化【S4】，输出为4x4，深度16"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('pool2'):\n",
    "    S4 = tf.contrib.slim.max_pool2d(\n",
    "        C3,[2,2],stride=[2,2],padding='VALID')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "【C5】,【F6】池化后的数据是3维的4x4x16， 这里做一个拉平的操作，将3维数据展开到1维，然后送入两层全连接，全连接隐层中神经元个数分别玩为120，84"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('fc1'):\n",
    "    S4_flat = tf.contrib.slim.flatten(S4)\n",
    "    C5 = tf.contrib.slim.fully_connected(\n",
    "    S4_flat,120,activation_fn=tf.nn.relu)\n",
    "    \n",
    "with tf.name_scope('fc2'):\n",
    "    F6 = tf.contrib.slim.fully_connected(\n",
    "        C5,84,activation_fn = tf.nn.relu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### 对特征添加一个0.6的dropout，以40%的概率丢弃特征中的某些数据，\n",
    "\n",
    "这样可以提高网络的推广能力，减少过拟合的可能性。\n",
    "\n",
    "需要注意的是，dropout仅在训练的时候使用，验证的时候，需要关闭dropout，\n",
    "所以验证时候的keep_prob是1.0。\n",
    "\n",
    "dropout的输出最终送入一个隐层为10的全连接层，这个全连接层即为最后的分类器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope('dropout'):\n",
    "    keep_prob = tf.placeholder(name='keep_prob',dtype=tf.float32)\n",
    "    F6_drop = tf.nn.dropout(F6,keep_prob)\n",
    "\n",
    "with tf.name_scope('fc3'):\n",
    "    logits = tf.contrib.slim.fully_connected(\n",
    "    F6_drop,10,activation_fn = None)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来定义loss和用于优化网络的优化器。loss计算使用了sparse_softmax_cross_entropy_with_logits,\n",
    "这样做的好处是labels可以不用手动做one_hot省了一些麻烦。这里使用了sgd优化器，学习率为0.3。\n",
    "\n",
    ">试试看，增大减小学习率，换个优化器再进行训练会发生什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Conv/weights:0\n",
      "INFO:tensorflow:Summary name Conv/weights:0 is illegal; using Conv/weights_0 instead.\n",
      "Conv/biases:0\n",
      "INFO:tensorflow:Summary name Conv/biases:0 is illegal; using Conv/biases_0 instead.\n",
      "Conv_1/weights:0\n",
      "INFO:tensorflow:Summary name Conv_1/weights:0 is illegal; using Conv_1/weights_0 instead.\n",
      "Conv_1/biases:0\n",
      "INFO:tensorflow:Summary name Conv_1/biases:0 is illegal; using Conv_1/biases_0 instead.\n",
      "fully_connected/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected/weights:0 is illegal; using fully_connected/weights_0 instead.\n",
      "fully_connected/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected/biases:0 is illegal; using fully_connected/biases_0 instead.\n",
      "fully_connected_1/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/weights:0 is illegal; using fully_connected_1/weights_0 instead.\n",
      "fully_connected_1/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_1/biases:0 is illegal; using fully_connected_1/biases_0 instead.\n",
      "fully_connected_2/weights:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/weights:0 is illegal; using fully_connected_2/weights_0 instead.\n",
      "fully_connected_2/biases:0\n",
      "INFO:tensorflow:Summary name fully_connected_2/biases:0 is illegal; using fully_connected_2/biases_0 instead.\n"
     ]
    }
   ],
   "source": [
    "cross_entropy_loss = tf.reduce_mean(\n",
    "        tf.nn.softmax_cross_entropy_with_logits(logits=logits,labels=y))\n",
    "\n",
    "l2_loss = tf.add_n([\n",
    "    tf.nn.l2_loss(w)\n",
    "    for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)\n",
    "])\n",
    "\n",
    "for w in tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES):\n",
    "    print(w.name)\n",
    "    tf.summary.histogram(w.name,w)\n",
    "\n",
    "total_loss = cross_entropy_loss + 7e-5 * l2_loss\n",
    "tf.summary.scalar('cross_entropy_loss',cross_entropy_loss)\n",
    "tf.summary.scalar('l2_loss',l2_loss)\n",
    "tf.summary.scalar('total_loss',total_loss)\n",
    "\n",
    "# 定义一个optimazer，它执行的操作是最小化total_loss\n",
    "optimizer = tf.train.GradientDescentOptimizer(\n",
    "    learning_rate=0.3).minimize(total_loss)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，上面的网络，最后输出的是未经softmax的原始logits，而不是概率分布，\n",
    "要想看到概率分布，还需要做一下softmax。\n",
    "\n",
    "将输出的结果与正确结果进行对比，即可得到我们的网络输出结果的准确率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "pred = tf.nn.softmax(logits)\n",
    "correct_pred = tf.equal(tf.arg_max(y,1),tf.arg_max(logits,1))\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 55000* 2 = 100*1100, 正好是2个epoch\n",
    "batch_size = 100\n",
    "training_step = 1100\n",
    "\n",
    "# saver用于保存或恢复训练的模型。\n",
    "saver = tf.train.Saver()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上定义的所有操作，均为计算图，也就是仅仅是定义了网络的结构，实际需要运行的话，还需要创建一个session，并将数据填入网络中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "after 100 training steps, the loss is 0.403735, the validation accuracy is 0.934\n",
      "after 200 training steps, the loss is 0.244579, the validation accuracy is 0.9498\n",
      "after 300 training steps, the loss is 0.111124, the validation accuracy is 0.9648\n",
      "after 400 training steps, the loss is 0.206197, the validation accuracy is 0.9702\n",
      "after 500 training steps, the loss is 0.205586, the validation accuracy is 0.9798\n",
      "after 600 training steps, the loss is 0.114882, the validation accuracy is 0.98\n",
      "after 700 training steps, the loss is 0.0551446, the validation accuracy is 0.9782\n",
      "after 800 training steps, the loss is 0.0384584, the validation accuracy is 0.9836\n",
      "after 900 training steps, the loss is 0.0473576, the validation accuracy is 0.9818\n",
      "after 1000 training steps, the loss is 0.0897718, the validation accuracy is 0.9812\n",
      "the training is finish!\n",
      "the test accuracy is :  0.9831\n"
     ]
    }
   ],
   "source": [
    "merged = tf.summary.merge_all()\n",
    "with tf.Session() as sess:\n",
    "    \n",
    "    writer = tf.summary.FileWriter('logs/',sess.graph)\n",
    "    \n",
    "    sess.run(tf.global_variables_initializer())\n",
    "    \n",
    "    #定义验证集与测试集\n",
    "    validate_data = {\n",
    "        x:mnist.validation.images,\n",
    "        y:mnist.validation.labels,\n",
    "        keep_prob:1.0\n",
    "    }\n",
    "    test_data = {\n",
    "        x:mnist.test.images,\n",
    "        y:mnist.test.labels,\n",
    "        keep_prob:1.0\n",
    "    }\n",
    "    \n",
    "   \n",
    "    for i in range(training_step):\n",
    "        xs, ys = mnist.train.next_batch(batch_size)\n",
    "        _,loss,rs = sess.run(\n",
    "            [optimizer,cross_entropy_loss,merged],\n",
    "            feed_dict={\n",
    "                x:xs,\n",
    "                y:ys,\n",
    "                keep_prob:0.6\n",
    "            })\n",
    "        writer.add_summary(rs,i)\n",
    "        \n",
    "        #每100次训练打印一次损失值域验证准确率\n",
    "        if i >0 and i%100 == 0:\n",
    "            validate_accuracy = sess.run(\n",
    "                accuracy,feed_dict=validate_data)\n",
    "            print(\n",
    "                'after %d training steps, the loss is %g, the validation accuracy is %g'\n",
    "                %(i,loss,validate_accuracy))\n",
    "            saver.save(sess,'./model.ckpt',global_step=i)\n",
    "            \n",
    "    print('the training is finish!')\n",
    "    # 进行最终测试\n",
    "    acc = sess.run(accuracy,feed_dict=test_data)\n",
    "    print('the test accuracy is : ',acc)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./model.ckpt-1000\n",
      "1.0\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nLz7m8UBKnT9nLqcnNtm7Yr30675l2kZD/Jys4lR7aXvZuyvtaOneXWnZMHtXspP3+9ZJ26V2oPDz\nF+zdm1p9sdnJp7PnJ6WcNYUe2MdZfu2gJwNL9qfpo+3umPCdo0eauP789TZh3R9OvrSNK2K/d5qt\n05x7LzTxgr8+7OTrlJlt4u1jcp20hqPsnfEKfl8T871qqszsnSbOK7Jxu0/ywyhOpcUzYSIiopCw\nESYiIgpJte2OzmjT2lleeE0bE7f42nY9NnjFvUNLWr6aePEu24WyosCd7tA2Y5OJR/0w0knbuNDe\n+afFt3Z7jb52u8d0yxYTN9zEbuVk0P57OctLLrLxywc+beJ+tSLmoiRqtL3B//ardjpJT22y3d2P\nfX+ok9blnIUmLtrh3mGtptrV0L071V617M9REez3ZvSzZzv52r7ztYkLUUZFds3Ol9vfgO613GlI\nc//yoIm/6P2mk9Z/sO3Gbvgiu6PTO+/hLM8fMM7El64+3Ob7/DuQxTNhIiKikLARJiIiCgkbYSIi\nopBUqzHh9EYNTbzfB0udtAm7vWfi/jPdcZ+grA/t9JTRx40yceH8Re57dbe3Xmuy6BcnrUnR4qjb\njn4TNyqLooPt2O8yOzSHD/o/6uTrlBGcWmbHgT/Z7k45u27BMBNvWu6O//8wzE5buX6NfXrW3S1n\nOvn61LEPIb9vv9ectH9ePsrEbe74GgQU1paYaXt+PcrE7W6ruM+ry0XTneX3B9uHzJ+SvcFJ2zR0\nq4kbvpjaclUFi26KfZvQipR/jJ3umdc2dhPXbJY75UxnhTPFkGfCREREIWEjTEREFJIq3R2dVtt9\n0lD+m7Y7+rrdJjlpXd+2fZbd3rHdDvGmOER2QTtpC39KsJSUDEtedqcevRRzupHbzXz60iNM/O2P\ndgpFt0sXOvmabbV13SzivS/oN9jEay9pb+LLH3enOY1pMdnEX25v5aTNudh2aQ978S8mLlixEjVV\n13/G7v5Ln1U/ZlpF+te3dpjilEHPOGkX9Zxi4vfRuMLKVFndv/9rMdO+ermviVui/MMLv7y0t7P8\n4P6vmLh3rakmbpGeFXMbP+9yBwj/8ublJu501TeR2VOGZ8JEREQhYSNMREQUkirXHZ3e2Hb7/Dg2\nx0lb1P0xE8+KuEd4t1uWmLgw170qjiqHtHruQxV+uqW3iRce6l71nBa40vnbwF3Ohr97kZOv6822\n2zlnk72auQiJ611/lYk/ybBd2jP/3c/J1/Q+e2XtsHqb4Ip9JXBNkrZnNxMPbPSJk7Z4l72T2G5z\nd1VYmeJp/EVgyGtQeOWorNIbNDBxvTT3R/d/2+33ueX9iXVBS6a9i9rOQXs6af96/FkTD6g9y0nL\nFPt7MCPfdkGf9eMpTr4r9vifiYfW2+akPTbMDjc8MO4EExcuiD7bJVl4JkxERBQSNsJEREQhYSNM\nREQUkio3Jrz6zO4mXnSC+wDu97ba8eJnjj/CSStc597ViiqfTUN7O8uTTrnHxGlwH+z+2XY77nPn\nhfYpVp3/504tSPQpO5JhvwppXTs5af+Z0MTE/37+ORP3rrU2Yiu2jOniHt/2nn6GiVuvrbl/iz+N\ntHdVOi17nZN28NwRJm7w329Bld/Sy3qZ+ODanzlpPT4/y8SdMTvmNoJPX1p0UQsTL/jrw9GyAwA+\n257tLF/48SgTd3twvYmzFrvftUdhryN6+LO2Ttr73d428R3t7HTXWgtiFiMpeCZMREQUEjbCRERE\nIaly3dF5+2+PmfbgUvvg6DqLa26XX1Wl7g2osENjT+vJK7J3xvp9fzutYfuJ+zn5Onf5Ler6m3e4\nd1s7pb190PhFjV5w0mbutNvvnxWc3OR2kQd9tcOdBNX6Vrsvmp8fmb3GuPyYD0wcnJIEALUebRpY\n4ve3KpA9Y0/3zPylTsy0oOCDH34cZKciRk4jHL7kGBPnXt3aSesyzU4PTHQI6uclLd0XukXPl2o8\nEyYiIgoJG2EiIqKQVLnu6Ff6PxVYco8h3uxhH+p54H1XOml7vLfTxOmTvwNVPo3fdW/of/5Zw038\nYjf3ga1D69m7ZJ30d3untEKNfS+sfLU3bM+SeH/6bprbBW0VRHR8DZx7mombXOSm6ZJwnlVamT25\nYYCzXPv9GSGVhMqqW/M1pV5H+vV0lt85+PHAUqaJek4+38nX5Rx79zvZ8X2p37ckN6y1zyGuPXme\niUtzd72y4JkwERFRSNgIExERhYSNMBERUUiq3Jjwfll2zGCXuuNujdPstJMfT3WfurPrrzZvr88u\nMHHDb92pKlva2LHGBvbBS9ht7taYZVq/p/v0nxaT7Z2UCjlVKmFFeXnOctaRdvn8Fic6aQtv6mDi\nI/vZ8ZvFm5s7+X5dtZuJ02vZv4GhXec6+e5uOROl1eNzd8yq65X2aUsFayLvplUzpTdq6CzXT1sZ\nUkkoFdrUtU8LS4s8pxNFNIsvyXKWu2fa3/R+355p4k7D3btsJXtsNjN7p7O8tcCWq2jHjsjsKcMz\nYSIiopCwESYiIgpJleuO3mPieSZefPwTCa8XfOjzosFP24TBSSmWY8a19u5Ily0ITFs5PrUPh67O\nCiO6d3P+bpeXBV6vhV+dfF0ilov9750eznK87uhlBfbh38Mevtpu+wF3Sk1hQQHItfIcdzrK8Pqf\nm/i7rR0quDSll3/s5php24pqxUyrKYrUnscVRXYYx7jjXasWm5zl4Ho9mtkpTxuTUL5IwYdFzB8w\nzkkbMPevJm5QgXds45kwERFRSNgIExERhYSNMBERUUiq3Jhw14vsZetHveFOETnrkYkmrpvmPqnm\n+Lr2AeLB8eFU2C/LXpo/de+XTNzz35c4+TqNnpbScpBr6e0Hmvi7fe+PSI09vnfy3XYcePdHvzZx\n9AkYVJUVHNbPWX5170cCS+7Umnfusk9ta4hvUlmsaqXROe70n+lf2ilKj7Szv+EH3nWVky/nIXt9\nR8Gq1WV67+6v2W2sKXSfyFf7wSaBJY4JExERVXtshImIiEJS5bqjNTANJPPTWU7aK912j7neQyfb\nqUKFmfbS+YOucqeZ3Nny2/IW0RG8i0ybPtEfME+ps3r0QSb+ePjdJq4jdWOu8+DGzs5yy2fnmDjV\nT1Shihfsgv7jUvfOeN0ybRf0hav6O2mNXrNPY6spQxPBKT4AMKDhpFJvI7Ir+a7Bw0zc5y17m8If\nznzIyXfhoYNM/NtxTZy0wg1/mHjTCDvsdPBl0518N7T4ysT9XnW7uzt9FM6QAs+EiYiIQsJGmIiI\nKCRVrju6rOq9OT3q6xP7HOgs3znCdkdvU3uD735T/u7ka/8fe4X1+ku2OWkz93UfQE8VZ9eR+zjL\nEy62XdDtMmJ3QS8P3BXrvWsOd9KytiV3iKImabDMfchK8O5jYZIM+9O36XL7oJCZfV918n2yvY6J\nF1/v3v2r1q7SP/Sjqiv8eamz/Orv+5n4hE4fOWntD15u4vQGDew2cnOdfAVLlpl41t72vHDACHc2\nSZO59k5bstsuJ23pI21NPH+AvaI98groYBd0p6sqxxXtPBMmIiIKCRthIiKikLARJiIiCkmNGROO\npd3H7p21MMKGdcXeRWnhoc+42dofYeL/dvg4YqvRj22W/+5eVt/Fef4PJcOy4927oXWIMQ78W6E7\nNnnWZVeauO4H0a8foNKr95b7WX40truJO9Ve56T91KaXiQtWrir3excdvJeJl17opp3U3U47u725\nOw4cdPtVI01c5+MZMfPVVDvOtWO9973VzUl7v9u7Jr70Mzu9a8YT7nU42aujP31s3b7uhMB9L7HT\nl+7dfaqTFpwK+tTmDiYef8/xTr5O4yrfXQp5JkxERBQSNsJEREQhqfHd0Zkzf3KWD/judBN/0/eV\nmOu90OGTwJJ7LJOv9vL54xfYO3V1u8S9Kbg7eYPKKr2p7eaffeIDEalZiGbg1Iud5U7vsAu6ol3Y\nyJ3usuZ927U584925d7+nXs8ZeK9asX+qZu1034TR8w4x0nrNOlHE/P7+meFi+1v2pS/uFO4Gn9g\n7z52/+5f2oRbvkQswW7lolLcn67X1L+ZuPMV603cZFXl636OxDNhIiKikLARJiIiCgkbYSIiopDU\n+DHhorw8Z7nlPxqbeMi4oSa+rsMHTr4Ds+wI0VtbdnPS/vXfU03c+XJ7azSOKSVPemNbT5dNt2NM\n2RJ9DBgA7tpgp8d0Oc+9FoBPR6oYwSkjay+d4qTd3Ox7uxCMy8z+vBVEfPu+t3ekxZmv2dsj7nGt\nO4bI72zigrefBIAJA+2Us4f+Zp+UtHUP95aTHx9tr+M46uPLbEKcR1N1/c8OZ7nDt3NtORIpbCXC\nM2EiIqKQsBEmIiIKSY3vjo5UsMw++QOH2fCSS9xb7uTta5/O0W3Meiet86+V4+kc1dn6ofbuPEfW\n/dzEhXG6sP5780AT19vKKUlhaBK4Y9G3U3KctPsm2C7GKxq7wwVl0e2Ls01ca55757Q2d3xt4j1Q\n+aexVEWFa9aauPWda2Pm+wfs3bRykNgTy+J8zascngkTERGFhI0wERFRSNgdnaAWD33tLgfiqnY1\nXnVw0lWfmrhQY1/b3HniBSbOeYtd0JVJ5APiP+1V38boW+7td8SckjMRhYxnwkRERCFhI0xERBQS\nNsJEREQh4ZgwVUl96tipZOlijyW/2eHe46jH3XZqBMfuiaiy4ZkwERFRSNgIExERhYTd0VQlXfaS\nffj6j+c9ZuKzx/3Dydd2iTu1jIioMuGZMBERUUjYCBMREYWEjTAREVFIOCZMVVL7G+1Y71E37mXi\ntuAYMBFVHTwTJiIiCgkbYSIiopCIanV6PDIREVHVwTNhIiKikLARJiIiCgkbYSIiopCwESYiIgpJ\nlWmERWSUiBSKyBYR6Z7gOpNEZIeITI2TZ5mIbBeRF5JX2oonIoP9z6ZIRAaHXZ6SsD7jY32aPKzP\nSogM0BwAABXOSURBVIJ1DIjILyKyU0ReTNY2Q2+ERaS7X1GbReRnETkhTvZpqpqtqgv9dbNE5H4R\nWS0iG0XkMRHJLM6sqocBuCCBYgxR1RGBMo0VkXkiUiAiN0Up8xki8quIbBWRCSLSJJCWJSLjRCRX\nRH4XkStK2P942xotIutFZL6I9A683l9EJgS3o6qfqmo2gOUIkYg0EZF3/P35VUTOiJPdqU9//cv9\nzy3X/xyzitNYnxVPRC4WkZkiki8i40vIHvn97CUiH/v7/KdpGKzPykFEJvsN5Rb/36I42SPrONgw\nF/8bWJy5HHV8kIjMEJE8EZkrIgcH0kRE/iUiy/16fFVEGsTZv71E5Evx2piVInJ9IK2PX3/rg38L\nIpIpItNFpG1wW6raCcDtCexPwkJthEUkA8C7AN4H0ATA+QBeFJGcBDdxLYB9APQCkAOgL4AxSSja\nzwCuBvBBlDL3BPAkgBEAWgDYBuCxQJabAHQB0B7AIABXi8jR0d4k3rZEpBWAcwB0BPA4gDv81zMA\n3AvgsvLtYso8CmAnvP0ZDuBxfz9LJCJHwavTw+F9fh0B3JyEMrE+y241gFsBjCvDursAvA5vv5OJ\n9Zl8F/uNa7aqdi3lutMC62ar6uTyFMQ/0JkI4N8AGgG4G8BEEWnsZzkLXp30B7A7gDoAHo6zyZcB\nTIHXxhwK4EIRGeqn3QHgKgB9APxLRFr6r18B4C1VXVGefUlE2GfC3eB9iPeraqGqTgLwFbwPOBFD\nADysqn+o6joADwE4u7yFUtXnVPVDAHlRkocDmKiqU1R1C4DrAZwoIvX99JEAxqrqRv9o8SkAo2K8\nVbxttQMwW1VzAXwK78sOeF/u91R1WXn3M9lEpB6AkwBcr6pbVHUqvIOsROtzJIBnVHW+qm4EcAti\nf3YJY32Wnaq+raoTAGwow7qLVPUZAPOTXCbWZ/V2EIA1qvqG3y68CGAdgBP99CEAxqnqCr9e7gJw\nqojUjbG9DgBe8rf1C4CpAIpPDPYAMElVVwH4CUA7EWkP73fs/lTsXKSwG+FoBN6ZLURkU7AbIsF1\n24hIw5SUzNMTwPfFC36l5gPI8Y/UWgXT/TjWmWDMbcE72u8tIo0ADAYw3+8aOQ3APUnbm+TKAVCg\nqosDr5n9T6A+nc/Dj1uISNOklzTGe7I+E1eG72dFYH2WzR1+l+xXwe7kBOt4b3/dxSJyvd8bkGym\nXYiRlgWvhyOaBwCc5XcxdwVwILwDJwD4AcCRItIGXmP9C4AHAYxW1V1JKntcYTfCiwCsBTDa/4CO\nhNddUBcAVLWRfzYVy0cALhWRZn43wiX+67GOiJIhG8DmiNdyAdT30xCRXpxWqm2p6gYAtwGYBOA4\neF0mDwK4BsAJIvKFiLzr//FUFtnwyh9k9j+B+oz8PIq3FevzSwbWZxklUJ9hYH2W3jXwzuRbw+sZ\nmCginYCE6ngKvMaxObyzx9MBjC5neaYBaCUip/ntwkgAnWB/1z8CcK6IdPBPuK7xX4/1u/8+gJMB\nbAfwI7zetm/9tKsA/B3AewAuh9fFnQdgqV9/X4jIKeXcn7hCbYT9I41h8P6IfwdwJbwxpJUJbuI2\nALMBzAHwNYAJ8Mah1kTLLCJPBC4euK6Mxd4CIPIigIbwKm6Lv9wgSlpptwVVfUVV+6rqMfD+0PPh\n7e898Lpk3kDlOuqOuz9lWL+4RyPq+qzP6oX1GQ5Vna6qeaqar6rPwRsSPDbBdZeo6lJVLVLVefCG\nkE6OlT+ROvYPcIbBaw/WADga3plrcbswDsArACbDG+r43H/9T+2GP778kV+u2gDaAjhKRC703+tX\nVT1WVfvCGzobC69hvgfAawCGArhPAhfkJVvYZ8JQ1bmqeqiqNlXVo+Adkc1IcN3tqnqxqrZW1Y7w\nxq1mqWpRjPwXBC4eKOsVbvPhDeIDAPwjxloAFvvjmL8F0/041phYzG0FM4lIHXhX5F0Jr8tlhT8W\n9S2APcu4H6mwGECGiAS7heLtfyTn8/DjNf6X8k9Yn9UL67PSUHhdvElfN9E6VtUvVHVfVW0C75qS\nbvDbBb/Bv1FVO6hqG3j1tMr/F6kjgEJVfV5VC1R1JYBXEf0g4wYAT6vqGgC9AcxU1c3wGvfOCex7\nmYTeCIvIniJSW0TqishV8MZsxie4bmsR2V08B8C7cOLGJJQpU0Rqw/t8MvzypfvJLwEYIiKH+Bci\njQXwtqoWH00/D2CMiDQWby7deXH2p6RtFRsDYLyqroY3xaGriLSAd3XnkvLub7Ko6lYAbwO4RUTq\n+WNJQwEkOv/veQDniEgPf/zueiT4txAP67PsRCTD/+zSAaT7n11CY37+97I2vIYL/rpZJayWyHZZ\nn0kiIo1E5KjiehWR4QAGwDt7TGT9Y/x9hYh0g/edfTcJ5drbr+cG8M5KV6jqx35aExHp5P999QBw\nH4BbYpx8LfZWkTNEJE28YctTAcyNeL8eAAbCu9IdAJYCOMzfty5I5dQyVQ31H7zL0DfC6/r5EEDn\nQNoWAIf48SgAUyPWHQBgGbypA4sADI+y/T+tF5G+DMDgiNfGwzuiC/4bFUg/w6+UrfD+4JoE0rLg\ndZfkwutKuSJi22afStqWn94N3hF1euC10QDWA1gAoHdJ+1PB9dkE3rDAVn+/zki0Pv3Xr/A/t1wA\nzwLIYn2GWp83RfnsbkqkPuFd6BK57jLWZ3j1GeXzbeaXPw/AJgDfADgi2ucRo47v8T/HrfAOOG4B\nkJmEOn4F3nj8Znjdws0DaTnwfu+3Afg1Sh0+AeCJwPJh/j5uhjfs+TSAuhHrfA5g/8ByH7/+1kfZ\n/k0AXkxaHYT9R1CKP5YR/oe+CUD3BNf5xP/j+ixOnkX+F/K5sPexnJ/P4f5nsx3AoLDLw/pkfbI+\nq259so7jlnULvClSSdkmnydMREQUktDHhImIiGoqNsJEREQhScWdTWI6Iu0U9n2H5JOiN8o65SAm\n1md4UlGfAOs0TPyOVi+J1ifPhImIiELCRpiIiCgkbISJiIhCwkaYiIgoJGyEiYiIQsJGmIiIKCRs\nhImIiELCRpiIiCgkbISJiIhCwkaYiIgoJGyEiYiIQsJGmIiIKCRshImIiEJSoU9RIiJKpp/vP8DE\nv5z6hJN21q8DTLzmwNwKKxOVTsFh/Uy89ATbJF15+H+dfOc3XGbiNLgPKCqCfVjUjWv3NvHEZb2c\nfLvfkW4XZswrU3mTjWfCREREIWEjTEREFBJ2R1O1ltGyhYk39+9g4lVHuM86Xzr0KRPv0kInrf+c\n00y8bkVjE/e483cnX8Gy5eUqK5Ve/wMWxEx7vv0UEx9ywv85aXXfmZ6yMtVUq645yFne2mWniU/v\nNyPmejc3t9+9IhSZOC3iHDGY1n3y+U5a8/eyTFz/tW9MvDti/31UFjwTJiIiCgkbYSIiopCwO5qq\nPMmyXVFLbu7rpD1y8n9MfGidbTG3sUvt8Wiw2wsAvtzrZbuwVyBseraTr90pCRWXkijY5RzP6gHu\n1bSd30lFaWq27y95xFkOXrG8pnC7iR/b4HZb53xohwrq/VTLxLXXu0NGTZ+ZZuJOmF2+wlYiPBMm\nIiIKCRthIiKikLARJiIiCgnHhCMUDrRjihk3rDHxxK7vOfkyxd55Jd6Ulqb/yjSxLFvl5NswpIeJ\nm0z4wUkryssrTbFrtOWj7R135o14sEzb+Nuvh5v4mfafJLTOnIPGOctDsW+Z3ptSr/Pl35Scicpl\nwLyTneVJvV8zcXAceNbe7rlfDmamtmCVHM+EiYiIQsJGmIiIKCQ1sjs6OKUlb+heTtqNd9guxuCU\nFnfSCrArcPV8vCktfa8fZeI+Ld1jnnc72Ev69230DyetxcNfRy88AQD0wD4mHnf2w6Vef89nL3GW\n9xj7nYm73X+Rk/bjXx4t9faJappG5+10lt//rKmJhzWaZeI53c9w8hUu/Cm1BavkeCZMREQUEjbC\nREREIWEjTEREFJIaOSacP7C3iSc98EjMfJ9vzzbxDbe6tyjM3KaR2Y3c9vbYplbgTolXX+VOadlc\nVGDi7N/caU7kCo4BA4De+oeJ+9kh/j+N3b+zpbmJx40aauIO092numiR/fy7Xv69k3bMhL+beOwT\n9okv+2S5dTb4Bzut7NNe9SN3gVKg02sXmPiXU5+Ime/n+w9wljllKfkKVqx0lq99Z7iJF5xpf2d3\ntnS/G+kLU1uuyo5nwkRERCFhI0z/3979x1R53XEcP/xQBFud2IlVQFCLqNVBFX+tWHUmtUaZbrqM\nzrWaWufmnKvOmWo3mduyNiad1ahxak1rba2spdQlU7eW7keUqpShU3FRkNXOVmZFHasoXvbHlu95\nvjfcuwvCPQjv11+f4zlcngQvX57z3HMOAMCRDjMd7Z3O/MXmLQHH5Z6dKvnq6iTJPYoONTa8Ud0H\npkrOyD8reXBn/TdPeuFTktN+zSHjwVzM6qraR9Lt1L5397IrPr1MYvUeu3tZyqHQfoYNdXWq3emA\n3dFnzn47/Xliun6UsTze/qy3vva46kvN1VPcaBnBpqDhmOfgqkhP49LQLmpYfMQIE4qYo3Yp062r\nV2/v2toQ7oQBAHCEIgwAgCMdZjr68ip7qLT307RTy7+ixkX9oJvNpR+Y5qgZkSB5da89AcclHWjW\ny3dIkZMvqbZ3lzLv7mXzKnLUuJQfhf4YIRRp37afqt7w4FDVtzS+XPI3hhxRfQdNZwO0Z9FJiar9\n7Ixdkn3GvkmLn9aHrER67gW97+tIv3vECcdnS67L1++9nttb9n0eTtwJAwDgCEUYAABHKMIAADjS\nbp8JV+4ertonMndIPl9vnw9HruqhxjWUHmvy9/KeymSMMQO/f9K+vufvHO/B8cYYE/uW3rUJWnTf\nPpKXDfp9SF9TkX+faieY6ha9Jq8XCyer9tJ55QFGAu2T9znw1P16GV5O18uSV1/MlLz33P1qXEPx\n5xp97Zyv/1m1l/a3vwNmrKlRfb419pnzlG8ukOxd1mRM21zaxJ0wAACOUIQBAHCk3U5HPzZET/V6\nP/peVW+XIZnipk8/G6OnoE+v04cLFCbbQ+C9BwpUrR2kxsUZdskK5vKDyZJn3VUYcNyCDydI7uvZ\nocwYY+qNG/fH6s3sD/efJLm+4lyYrwZoHf/KsI+MFnTX79Hxx74mudsj9n3Zx5w0oSh5Tt8jliVm\nS35mfj/VN2bKccn7dtpDVjbWDFDjfjvPvoY5fNy0BdwJAwDgCEUYAABH2u10dEuLGqqnkk8t7i65\nfPpG/+HCeybx3QcrVR8nCAdX/UDE/x9kjDn77GDJsR+3jU+cT+uqd/h6fmRvyXcxHR12nB/cOrrs\nte+3aXv1QQzdzFn/4bel/vxHkpPzPlJ9/8izOXPFYsn+n7D+6ev24Jenn1io+qLfLWmBq2w67oQB\nAHCEIgwAgCMUYQAAHGm3z4TfqMxQ7eU97cfRM2NqJWcfux7S642Ke1O1J8bar/P5D/ZYVjZLcuIn\nJ0L6XvivW3GBT1Txais7j3WKiJLsPdkJQPj0fe6g5LJdSarv3v1XJK/ZtlX1Lfn5IsnhPJWJO2EA\nAByhCAMA4Ei7nY7uPUd/hD3nrZmSf5Nud3bxTlM3RbbnY/C+XL0c5U8Zr0rutTWuWa8PY4YPPyfZ\nF3TSv2242WAXnd0J1wu0d95lTcYYk7/yYckX8vSytU3PrJf8eNISycl5B01r4k4YAABHKMIAADhC\nEQYAwJF2+0zYd+2a/ocv2fakmd+RfHFE4L9Depyy60y679LPD6p31kkuz9it+rZfSZEcd+KCZFcn\n+iD8qupvqHZs9Y0AIwGES2yhXc5YVhJ4+dJfnnxBck5eVqteE3fCAAA4QhEGAMCRdjsdHUxcwfuS\nUwqa9xrlk7ZJ9l+OsvH0Q5L7fBjaAda488yfcSBg35d3LFft5KLWXebQUT1WNV7yy/3+GHDcmV+O\nUW1OVYL/8qX1ZRMlL3yoImzXwZ0wAACOUIQBAHCkQ05HN0fU0EF+/2IPgPb/JGzC+i5huKL2r/bH\nfSQf3RGl+kbG2N2p/p4/THLy7ObtgNYcWbGVqn24LkJyytoy1cf+WUAbM2qYau4cs13yxpoBYbsM\n7oQBAHCEIgwAgCMUYQAAHOGZcIgqVncO2De7dL5q9y76oLUvp0OI/EOp5EXrvqv6jqzYIPl3ozdL\nnjvxe2pcVAv/LCp3D5f8xS4lqm9caa7k+Nq/tej3hfXvmaMlv9xvi8MrgVfVT8apdpd/2pywoW0s\n0Ysakib56ppa1ZcY/ZnkfXOzPT2t+zkT7oQBAHCEIgwAgCNMRwfRMPYLkt8evcmv1y5DininR5iu\nqOO6971PVXvkpDmSj2a9Ivn8BL08rF/R7X/v2q/a6c89o+3B34fqYtS4+J+xNC0cUn94yvUl4H8u\nPTFW8vH5G1Tf4PfsY7oE3XXbopMSVbvq0eRGx/Wfqne+Wpn0muTiz/QypJl5dpe7+COHbvcSQ8ad\nMAAAjlCEAQBwhCIMAIAjPBMO4mJWV8mp0fp5n/fkpOjrDWG7po7Kd6xctfuustuIFhTES3577lo1\nbso9SyXft+h9E0jEiKGSPxnbXfVtWWYP+B7c2f7dmr53gRqXVnzYoOV5lyQZE/qypOxF35I8sIBT\nk1pbpwi9teypCfakudJK+/vy0UNPqnERnjy+/xnJp2t6qXFFw/IlRxq99NBnGjx99hU31aSqcbnv\n2v8TQ/IuqL748+F7DuzFnTAAAI5QhAEAcITp6CCu32OnOHx+5+Cs+3SI5J5b3UxjdGS3TpyW/NIU\nexj3ll/pn9O+ac9L3pM9QvLuVyepcdsW2DUUmTGBzzyacnKW5PTN11QfJyWF34DXF0oe+JSeco4z\ngR8/oGX03G5/942rXaj6Lk6va/RrXhq7XbVHxdjfs97Ti3xqolovefJd0jsY9i+42ej36lxyRrXT\nrh6VXN/oV4Qfd8IAADhCEQYAwBGmo4OYMyPwdksvFk6WnGKYjnapvuKc5Jjcz6u+hZlLJHda8bHk\nksUvqHHpexcFfP3UN+1Ec0zRMcm+mzeafK1ourgCPa38cEGG5IGGTz23FXfvLvZrNz5ujXkgxFfU\nj3sGmNIA4wK71eSvCD/uhAEAcIQiDACAIxRhAAAc4ZlwEG9U2mdPy3u27sHOaBm3qqtVu9MBT/uA\njTkmS41LM6HtdsXeaABaEnfCAAA4QhEGAMARpqODaHjHHgywMlFvIp9w9E748DsAoC3jThgAAEco\nwgAAOEIRBgDAEZ4JB5Gw/qDkv67XfbEhLmkBACAQ7oQBAHCEIgwAgCMRDQ3sAQQAgAvcCQMA4AhF\nGAAARyjCAAA4QhEGAMARijAAAI5QhAEAcIQiDACAIxRhAAAcoQgDAOAIRRgAAEcowgAAOEIRBgDA\nEYowAACOUIQBAHCEIgwAgCMUYQAAHKEIAwDgCEUYAABHKMIAADhCEQYAwBGKMAAAjlCEAQBwhCIM\nAIAj/wG0ikXZ8MQAiAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x12d413940>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    ckpt = tf.train.get_checkpoint_state('./')\n",
    "    if ckpt and ckpt.model_checkpoint_path:\n",
    "        saver.restore(sess, ckpt.model_checkpoint_path)\n",
    "        final_pred, acc = sess.run(\n",
    "            [pred,accuracy],\n",
    "            feed_dict={\n",
    "                x:mnist.test.images[:16],\n",
    "                y:mnist.test.labels[:16],\n",
    "                keep_prob:1.0\n",
    "            }\n",
    "        )\n",
    "        orders = np.argsort(final_pred)\n",
    "        plt.figure(figsize=(8,8))\n",
    "        print(acc)\n",
    "        for idx in range(16):\n",
    "            order = orders[idx,:][-1]\n",
    "            prob = final_pred[idx,:][order]\n",
    "            plt.subplot(4,4,idx+1)\n",
    "            plt.axis('off')\n",
    "            plt.title('{}:[{}]-[{:.1f}%]'.format(\n",
    "                np.argmax(mnist.test.labels[idx]),order,prob*100\n",
    "            ))\n",
    "            plt.imshow(mnist.test.images[idx].reshape(28,28))\n",
    "            \n",
    "    else:\n",
    "        pass\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "代码不作为评判标准，如果运行正确，则认为代码没有错误。 \n",
    "\n",
    "#### - 没有明显报错的正常的log输出 60分。 \n",
    "\n",
    "log输出如上面各个步骤所示\n",
    "\n",
    "#### - 卷积的特性描述20分。\n",
    "\n",
    "**卷积的特性：**\n",
    "\n",
    "    1.局部相关性\n",
    "    \n",
    "        相邻像素结合起来表达一个特征，距离较远的像素影响较小\n",
    "        \n",
    "        随着层数的增加，feature map里面的垫映射到原图的感受野越来越大\n",
    "        \n",
    "        不仅仅可以适用于图像，其他具有局部相关性的数据可以尝试卷积网络处理\n",
    "        \n",
    "        有一定的遮挡不变性\n",
    " \n",
    "    2.参数共享\n",
    "    \n",
    "    3.平移宽容\n",
    "        \n",
    "        在任何位置都可以激活神经元\n",
    "        \n",
    "    4.缩放宽容\n",
    "    \n",
    "        一定程度内的图像缩放（25%以内）不会产生太大干扰\n",
    "        \n",
    "    5.少许降维\n",
    "        \n",
    "$(H,w)_{output} = ((H,W)_{input}-(H,W)_{kernel}+padding*2)/stride + 1$\n",
    "        \n",
    "        如这个例子里面，将28*28，经过一次卷积，变成了24*24，还有一次卷积从12*12降维到8*8\n",
    "    \n",
    "    6.对输入的尺寸不作要求\n",
    "    \n",
    "        全连接里面，权重W的尺寸是由输入决定的。\n",
    "        \n",
    "        卷积核的尺寸只与网络设计有关，与输入没有任何关系\n",
    "        \n",
    "        卷积核固定的情况下，feature的尺寸是随着输入变化的\n",
    "\n",
    "\n",
    "#### - 为什么卷积的效果要比全连接网络好，给出至少2点理由，每点10分。 \n",
    "\n",
    "    这个问题我觉得是从卷积带来的各个特性来看，感觉其中比较重要的是：\n",
    "    \n",
    "    1.卷积考虑了图像的局部相关性，每个卷积核都是将一定区域的数值结合考虑的。而全连接网络是将每个像素看作是单独的输入。因此在识别图像这种功能上，卷积可以从更宏观的角度去识别图像，就比全连接网络要优秀了。\n",
    "    \n",
    "    2.网络层数越多其表达能力越强，但是通过梯度下降方法训练深度全连接神经网络很困难，因为全连接神经网络的梯度很难传递超过3层。因此，我们不可能得到一个很深的全连接神经网络，也就限制了它的能力。\n",
    "\n",
    "    卷积神经网络采用局部连接 每个神经元不再和上一层的所有神经元相连，而只和一小部分神经元相连。这样就减少了很多参数。\n",
    "    \n",
    "    3.权值共享 一组连接可以共享同一个权重，而不是每个连接有一个不同的权重，这样又减少了很多参数。\n",
    "    \n",
    "    4.下采样 可以使用Pooling来减少每层的样本数，进一步减少参数数量，同时还可以提升模型的鲁棒性。对于图像识别任务来说，卷积神经网络通过尽可能保留重要的参数，去掉大量不重要的参数，来达到更好的学习效果。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
